/*
 * Albareth - an action roleplaying game.
 * Copyright (C) 2008 Jens Anuth
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 *   02110-1301, USA.
 * 
 * $Id: ActionBar.java 43 2008-05-13 16:52:12Z jens464 $
*/
package albareth.frontend.slick.ui;

import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;

import albareth.core.entity.Activatable;
import albareth.core.entity.Asset;
import albareth.core.entity.Item;
import albareth.core.entity.ItemContainer;
import albareth.core.entity.ItemContainerChangeListener;
import albareth.core.entity.PlayerCharacter;
import albareth.frontend.slick.SlickResources;

public class ActionBar extends BasicMenuFrame
        implements MenuListener, ItemContainerChangeListener
{
    private static final String[] _shortcutStrings = new String[] {
        "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "", "",
        "A+1", "A+2", "A+3", "A+4", "A+5", "A+6", "A+7", "A+8", "A+9", "A+0", "", "",
    };
    //private Frontend _frontend;
    private PlayerCharacter _player;
    private int _numButtons;
    private boolean _altKeyDown = false;
    
    
    public ActionBar(PlayerCharacter player,
                     int buttonWidth, int buttonHeight, int columns, int rows)
    {
        super(new ActionBarMenuView(player,
                buttonWidth, buttonHeight, columns, rows));
        _player = player;
        addMenuListener(this);
        setCurrentSelectedIndex(-1);
        setDraggingAllowed(true);
        setDroppingAllowed(true);
        setSelectionUpdatedOnMouseOver(true);
        _numButtons = columns * rows;
        
        for (int i = 0; i < _numButtons; i++)
        {
            MenuItem item = new MenuItem("");
            addItem(item);
        }
    }
    
    public MenuItem setItem(int index, Asset asset)
    {
        MenuItem item = new MenuItem(asset.getName());
        item.setReferencedObject(asset);
        item.setShortcutString(_shortcutStrings[index]);
        item.setTooltipText(asset.getShortDescription());
        try {
            item.setIconImage(SlickResources.getTileImage(asset.getTile()));
        } catch (SlickException e) {}
        replaceItem(index, item);
        return item;
    }

    
    public MenuItem clearItem(int index)
    {
        MenuItem item = new MenuItem("");
        replaceItem(index, item);
        return item;
    }
    
    
    
    public void menuCloseRequested(BasicMenuFrame menu)
    {
    }

    public void menuItemSelected(BasicMenuFrame menu, MenuItem selectedItem)
    {
        Activatable activatable = ((Activatable)selectedItem.getReferencedObject());
        if (activatable != null)
        {
            if (_player.getActiveAction() != null) {
                _player.warnMsg("You are currently busy.");
                return;
            }
            
            activatable.activate(_player);
        }
    }
    
    protected void mouseLeft(int newx, int newy)
    {
        setCurrentSelectedIndex(-1);
    }


    /**
     * Removes the item at the old position.
     * TODO: replace completely by container listener!
     */
    protected void itemDraggedAway(DraggeableItem draggedItem)
    {
        for (int i = 0; i < _numButtons; i++)
        {
            if (draggedItem == getItem(i)) {
                clearItem(i);
                return;
            }
        }
    }



    /**
     * The bar accepts either useable Items or Spells, both implementing
     * the Activatable interface.
     */
    protected boolean tryDropItem(DraggeableItem droppedItem, int x, int y)
    {
        Object droppedObj = droppedItem.getReferencedObject();
        
        if (!(droppedObj instanceof Activatable)) {
            _player.infoMsg("This cannot be placed there.");
            return false;
        }

        int index = getItemIndexAt(x, y);
        
        if (index < 0) {
            throw new RuntimeException(
                    "Tried to drop item to invalid position."
            );
        }
        
        if (getItem(index).getReferencedObject() != null)
        {
            _player.infoMsg("The slot is not empty.");
            return false;
        }

        if (droppedObj instanceof Item) 
        {
            Item item = (Item)droppedObj;
            
            if (!item.isActivatable()) {
                _player.infoMsg("This is not useable.");
                return false;
            }
            
            //if it useable and not in my inventory yet, try to pick it up.
            //and only if that was successful, put it on this action bar.
            if (item.getOwner() != _player.getBackpack())
            {
                if (!_player.tryPickup(item)) {
                    _player.infoMsg("Could not pick it up.");
                    return false;
                }
            }
        }

        setItem(index, (Activatable)droppedObj);
        
        return true;

    }

    /**
     * The player's backpack has changed.
     * We check, which of our linked items are no longer in there and
     * remove them.
     */
    public void itemContainerChanged(ItemContainer cont)
    {
        for (int i = 0; i < _numButtons; i++)
        {
            MenuItem item = getItem(i);
            Asset asset = (Asset)item.getReferencedObject();
            if (asset != null && asset.getOwner() != _player &&
                    asset.getOwner() != _player.getBackpack())
            {
                clearItem(i);
            }
        }
    }

    public boolean keyPressed(int key, char c)
    {
        if (key == Input.KEY_LALT) {
            System.err.println("alt dn");
            _altKeyDown = true;
            return true;
        }
        
        switch (key)
        {
            case Input.KEY_1:
                menuItemSelected(this, getItem(0));
                break;
            case Input.KEY_2:
                menuItemSelected(this, getItem(1));
                break;
            case Input.KEY_3:
                menuItemSelected(this, getItem(2));
                break;
            case Input.KEY_4:
                menuItemSelected(this, getItem(3));
                break;
            case Input.KEY_5:
                menuItemSelected(this, getItem(4));
                break;
            case Input.KEY_6:
                menuItemSelected(this, getItem(5));
                break;
            case Input.KEY_7:
                menuItemSelected(this, getItem(6));
                break;
            case Input.KEY_8:
                menuItemSelected(this, getItem(7));
                break;
            case Input.KEY_9:
                menuItemSelected(this, getItem(8));
                break;
            case Input.KEY_0:
                menuItemSelected(this, getItem(9));
                break;
            default:
                return false;
        }
        
        return true;

    }

    public boolean processKeyReleased(int key, char c)
    {
        if (key == Input.KEY_LALT) {
            System.err.println("alt up");
            _altKeyDown = false;
            return true;
        }
        return true;
    }
    

    


}
